home *** CD-ROM | disk | FTP | other *** search
- /* $VER: Mailserver version 1.0 by D. Ramsey - dom@dynamo.demon.co.uk
- Mailserver (c)1995 D. Ramsey - dom@dynamo.demon.co.uk
- Freely distributable
- */
-
- call initialise
- call startup
- call get_listowner
- call get_prefs
- call get_externals
- call who_from
- call change_realname
- call send_receipt
- call process_instructions
- call update_log
- call clean_up
-
- /* Finished */
- EXIT
-
- /********************************************************************/
- :
- /* Initialise variables, wait for other copies of the program to
- finish, then open a lock file to prevent other copies running.*/
-
- initialise:
- prefsfile = 'mailserver:sys/prefs'
- externalsfile= 'mailserver:sys/externals'
- numexternals = 0
- inform = 'YES' /* Send mail to list owner when mail received? */
- keeplog = 'yes' /* Keep a lofile of incoming requests? */
- receipt = 'YES' /* Send a receipt with mail */
- logname = 'uuspool:mailserver.log'
- mailname = 'Amiga Mailserver'
- realname = '' /* Temp store for user's REALNAME */
- dir_cmd = 'list'
- dir_cmd_opts = ' '
- tmpnum = time(s)
- tmpname = 'T:ms'tmpnum'.tmp' /* The incoming mail file */
- tmpdir = 't:md'tmpnum'.tmp' /* Temp DIR file */
- tmpname2 = 't:mf'tmpnum'.tmp' /* Various Temp files */
- tmpuu = 't:uu'tmpnum'.tmp' /* temp uuencode file */
- lockname = 't:mailserver.lock'
- req_from = '' /* If Reply-To: then this holds requestor */
- domain = '' /* Only used if your sendmail */
- host = '' /* needs them. */
- publicdir = 'pub:'
- currentdir = publicdir
- sendmail = 'sendmail -f $FROMUSER -t $TO < $MSG'
- dirlevel = 0
- errornum = 0
- errormsg.1 = 'File / directory does not exist.'
- errormsg.2 = 'Root directory has no parent.'
- errormsg.3 = 'No such directory.'
-
- /* Copy stdin to temp file */
- if (open(tmpfile, tmpname, 'w')) then do
- do forever
- line = readch(stdin, 64000)
- /* Write to mail to temp file */
- writech(tmpfile, Line)
- if eof(stdin) then break
- end
- close(tmpfile)
- end
-
- /* Wait for other copies of the program to finish */
-
- do while exists(lockname)
- address command 'wait 3 secs'
- end
-
- /* Open lock file to prevent other mailservers running */
-
- open(lockfile,lockname,"w")
- writeln(lockfile,tmpname)
- close(lockfile)
-
- Return
-
- /*********************************************************************/
-
- /* Get the mailbox name of the list owner */
-
- get_listowner:
- if inform = 'YES' then
- do
- /* Work out email address of mailserver owner */
- open(tmpfile2,'ENV:username',"r")
- username = readln(tmpfile2)
- close(tmpfile2)
- owner = username
- end
- return
-
- /********************************************************************/
-
- /* Who is the mail from? */
- who_from:
- replyto = ''
- open(tmpfile,tmpname,"r")
- /* read in first line of header (junk) */
- line = (readln(tmpfile))
-
- do until (line='')
- /* read a line of the file */
- line = readln(tmpfile)
- /*convert to upper case for testing*/
- tst= upper(line)
- if left(tst,5)= "FROM:" then req_from = right(line,length(line)-6)
- if left(tst,5)= "FROM:" & replyto = '' then replyto = right(line,length(line)-6)
- if left(tst,9)= "REPLY-TO:" then replyto = right(line,length(line)-10)
- end
- return
-
- /* replyto now conatins return address */
-
-
- /********************************************************************/
-
- /* Send Confirmation slip */
-
- send_receipt:
- if receipt = 'YES' then do
- address command 'copy mailserver:sys/confirmation 'tmpname2
- open(tmpfile2,tmpname2,"a")
- writeln(tmpfile2,line)
- writeln(tmpfile2,'')
- writeln(tmpfile2,'Requested by: 'req_from)
- close(tmpfile2)
- to = replyto
- msg = tmpname2
- call send_mail
- end
- return
-
- /********************************************************************/
-
- process_instructions:
- /* Now get instructions*/
-
- do until (eof(tmpfile)|line='--'|line='QUIT')
-
- errornum = 0
- success = 0
-
- line = readln(tmpfile)
-
-
- /* Check for any external commands first */
-
- call check_externals
-
- line = upper(line)
-
- if (word(line,1)="DIR" | word(line,1)="LIST") then call dir
-
- if (word(line,1)="CD" | word(line,1)="CHDIR") then call cd
-
- if (word(line,1)="PARENT" | word(line,1)="CDUP") then call parent
-
- if word(line,1)="ROOT" then call root
-
- if word(line,1)= "HELP" then
- do
- /* Send HELP */
- address command 'copy mailserver:sys/help 'tmpname2
- to = replyto
- msg = tmpname2
- call send_mail
- end
- if (word(line,1)="GET " | word(line,1)="SEND") then
- do
- /* Send a file */
- file = word(line,2)
- call check_get_dir
-
- /* Check that file exists */
- if exists(currentdir'/'file)=0 then
- do
- errornum=1
- call send_error
- end
- else
-
- /* Send the requested file */
- if errornum = 0 then
- do
- /* First uuencode it if needed */
- do
- address command 'mailserver:sys/autoencode 'currentdir'/'file' 'tmpuu
- address command 'join mailserver:sys/headerfile 'tmpuu' as 'tmpname2
- end
- to = replyto
- msg = tmpname2
- call send_mail
- end
- end
- end
- close(tmpfile)
- return
-
- /********************************************************************/
-
- update_log:
-
- if keeplog = 'YES' then
- do
- /* Put a separator line in the logfile */
- open(logfile,logname, 'a')
- writeln(logfile,'Date: 'date()' 'time())
- writeln(logfile,'Request from: 'req_from)
- writeln(logfile,'Reply to: 'replyto)
- writeln(logfile,'')
- close(logfile)
- end
-
- /*Does owner want to be informed of mailserver access?*/
- if inform = 'YES' then call inform_owner
-
- return
-
- /********************************************************************/
-
- inform_owner:
- do
- /* Send a message to Mailserver owner */
- address command 'join mailserver:sys/mailslip 'tmpname' as 'tmpname2
- to = owner
- msg = tmpname2
- call send_mail
- end
- return
-
- /********************************************************************/
-
- clean_up:
- /* Clean up */
- address command 'delete >nil: 'tmpname
- address command 'delete >nil: 'tmpname2
- address command 'delete >nil: 'tmpdir
- address command 'delete >nil: 'tmpuu
- address command 'delete >nil: 'lockname
-
- if exists('ENV:REALNAME') then
- do
- open(tmpfile2,'ENV:REALNAME',"w")
- writeln(tmpfile2,realname)
- close(tmpfile2)
- end
-
- return
-
- /********************************************************************/
-
- send_error:
- /* send the error file */
- address command 'copy mailserver:sys/headererror 'tmpname2
- open(tmpfile2,tmpname2,"a")
- writeln(tmpfile2,line)
- writeln(tmpfile2,'')
- writeln(tmpfile2,errormsg.errornum)
- close(tmpfile2)
- to = replyto
- msg = tmpname2
- call send_mail
- return
-
- /********************************************************************/
-
- check_get_dir:
- /* Check the format of directories in a GET command */
-
- success = 1
- dir = ''
-
- do chr = 1 to length(file)
- temp = substr(file,chr,1)
- temp2 = temp
- if temp = '\' then temp2= ' '
- if temp = '/' then temp2= ' '
- dir = dir || temp2
- end
-
- dir2 = ''
-
- do wrd = 1 to words(dir)
- dir2 = dir2 || word(dir,wrd) || '/'
- end
-
- /* Remove trailing '/' */
- file = left(dir2,length(dir2)-1)
-
-
- return
-
- /********************************************************************/
-
- dir:
- success = 1
- /* Send directory listing */
-
- direc = ''
- if word(line,2) ~= '' then
- do
- direc = word(line,2) /* optional directory */
- dir = ''
-
- do chr = 1 to length(direc)
- temp = substr(direc,chr,1)
- temp2 = temp
- if temp = '\' then temp2= ' '
- if temp = '/' then temp2= ' '
- dir = dir || temp2
- end
-
- dir2 = ''
-
- do wrd = 1 to words(dir)
- dir2 = dir2 || word(dir,wrd) || '/'
- end
-
- /* Remove trailing '/' */
- direc = left(dir2,length(dir2)-1)
- end
-
- if right(currentdir,1) ~= ':' then direc = '/'direc
-
- address command dir_cmd' 'currentdir || direc' 'dir_cmd_opts' > 'tmpdir
- address command 'join mailserver:sys/headerdir 'tmpdir' as 'tmpname2
- to = replyto
- msg = tmpname2
- call send_mail
- return
-
- /********************************************************************/
-
- cd:
- /* change directory */
-
- success = 1
- direc = ''
- if word(line,2) ~= '' then
- do
- direc = word(line,2) /* directory */
- dir = ''
-
- do chr = 1 to length(direc)
- temp = substr(direc,chr,1)
- temp2 = temp
- if temp = '\' then temp2= ' '
- if temp = '/' then temp2= ' '
- dir = dir || temp2
- end
-
- dir2 = ''
-
- do wrd = 1 to words(dir)
- dir2 = dir2 || word(dir,wrd) || '/'
- end
-
- /* Remove trailing '/' */
- direc = left(dir2,length(dir2)-1)
- end
-
- /*direc now contains directory name or is empty */
-
- if right(currentdir,1) ~= ':' then direc = '/'direc
-
-
- /* Does directory exist? */
- if exists(currentdir || direc) = 0 then
- do
- errornum = 3
- call send_error
- end
-
- else
- do
- currentdir = currentdir || direc
- dirlevel = dirlevel+words(dir)
- end
- return
-
- /********************************************************************/
-
- parent:
- success = 1
- dir = currentdir
-
- if dirlevel = 0 then
- do
- /* command failed */
- errornum = 2
- call send_error
- end
-
- else
-
- do
- /* take the final '/xxx' out of the dir name */
- dirlevel = dirlevel-1
- temp = reverse(dir)
- chrnum = verify(temp,'/','m')
- dir = right(temp,length(temp)-chrnum)
- currentdir = reverse(dir)
- end
- return
-
- /********************************************************************/
-
- root:
- success = 1
- currentdir = publicdir
- dirlevel = 0
-
- return
-
- /********************************************************************/
-
- get_prefs:
- if exists(prefsfile) =1 then
- do
- open(tmpfile2,prefsfile,'r')
- do until eof(tmpfile2)
- line = readln(tmpfile2)
-
- if ((line~='') & (left(line,1)~='#')) then
- do
- /* process keywords */
- keyword = upper(word(line,1))
- value = upper(word(line,3))
- if keyword = 'OWNER' then owner = value
- if keyword = 'DOMAIN' then domain = value
- if keyword = 'HOST' then host = value
- if keyword = 'INFORM' then inform = value
- if keyword = 'KEEPLOG' then keeplog = value
- if keyword = 'LOGNAME' then logname = value
- if keyword = 'RECEIPT' then receipt = value
- if keyword = 'MAILNAME' then
- do
- /* Mailname's value can be more than one word */
- temp = wordindex(line,3)
- value = right(line,length(line)-temp+1)
- mailname = value
- end
- if keyword = 'SENDMAIL' then
- do
- /* Sendmail's value can be more than one word */
- temp = wordindex(line,3)
- value = right(line,length(line)-temp+1)
- sendmail = value
- end
-
- if keyword = 'DIR_CMD' then dir_cmd = value
- if keyword = 'DIR_CMD_OPTS' then
- do
- /* dir_cmd_opts value can be more than one word */
- temp = wordindex(line,3)
- value = right(line,length(line)-temp+1)
- dir_cmd_opts = value
- end
-
- if keyword = 'PUBLICDIR' then
- do
- publicdir = value
- currentdir = value
- end
- end
- end
- close(tmpfile2)
- end
- return
-
- /********************************************************************/
-
- change_realname:
- /* Try to find REALNAME env variable */
-
- if exists('ENV:REALNAME') then
- do
- open(tmpfile2,'ENV:REALNAME',"r")
- realname = readln(tmpfile2)
- close(tmpfile2)
- end
-
- address command 'setenv REALNAME 'mailname
-
- return
-
- /********************************************************************/
-
- /* Execute Amigados startup file if present */
- startup:
-
- if exists('mailserver:sys/startup') then
- do
- address command 'execute >nil: mailserver:sys/startup'
- end
-
- return
-
- /********************************************************************/
-
- /* call your sendmail commad */
- send_mail:
-
- string = sendmail ; search = '$FROMUSER' ; replace = 'mailserver'
- call substitute
-
- string = temp ; search = '$FROMREAL' ; replace = mailname
- call substitute
-
- string = temp ; search = '$MSG' ; replace = msg
- call substitute
-
- string = temp ; search = '$FROMDOMAIN' ; replace = domain
- call substitute
-
- string = temp ; search = '$FROMHOST' ; replace = host
- call substitute
-
- /* Add the To: line at the top of the mail */
- address command 'rename 'msg' 'msg'.bak'
- open(t,msg,'w')
- writeln(t,'To: 'to)
- close(t)
- address command "type "msg".bak >> "msg
-
- /* Send the mail */
- address command temp
-
- /* delete old copy of the message */
- address command 'delete >nil: 'msg'.bak'
-
- return
-
- /********************************************************************/
-
- /* Replace on substring in a string with another */
- /* Needs 3 vaiarbles set, string,search,replace */
-
- substitute:
- v = index(string,search)
- if v > 1 then
- do
- lft = left(string,v-1)
- rht = right(string,length(string)-length(search)-v+1)
- str = lft || replace ||rht
- temp = str
- end
- else temp = string
-
- return
-
- /********************************************************************/
-
- /* Get external commands */
- get_externals:
-
-
- if exists(externalsfile) =1 then
- do
- open(tmpfile2,externalsfile,'r')
- do until eof(tmpfile2)
- extline = readln(tmpfile2)
-
- if ((extline~='') & (left(extline,1)~='#')) then
- do
- /* process keywords */
- numexternals = numexternals + 1
- ext_keyword.numexternals = upper(word(extline,1))
- temp = wordindex(extline,2)
- ext_cmd.numexternals = right(extline,length(extline)-temp+1)
- end
- end
- close(tmpfile2)
- end
- return
-
- /********************************************************************/
-
- check_externals:
-
- do tempnum = 1 to numexternals
-
- if upper(word(line,1)) = ext_keyword.tempnum then
- do
- /* Found an external command */
- success = 1
- /* Replace %s with command line */
-
- string = ext_cmd.tempnum ; search = '%s'
- temp2 = wordindex(line,2)
- replace = right(line,length(line)-temp2+1)
- call substitute
-
- string = temp
- search = '$msg' ; replace = tmpname
- call substitute
-
- cmd = temp
-
- /* Add subject: and blank line */
- open(tmpfile2,tmpname2,'w')
- writeln(tmpfile2,'Subject: Your Request: '""""line"""")
- writeln(tmpfile2,'')
- close(tmpfile2)
-
- address command cmd' >> 'tmpname2
-
- to = replyto
- msg = tmpname2
- call send_mail
-
- end
-
- end
-
- return
-
- /********************************************************************/
-
-